#include "key_manager.h"
#include "stdio.h"

/**
 * @brief  初始化按键IO
 */
static void InitKeyIo(void)
{ 
    GPIO_InitTypeDef gpio_init_struct;
    
    /* 开启时钟 */
    KEY0_GPIO_CLK_ENABLE();                                     /* KEY0时钟使能 */
    KEY1_GPIO_CLK_ENABLE();                                     /* KEY1时钟使能 */
    KEY2_GPIO_CLK_ENABLE();                                     /* KEY2时钟使能 */

    /* GPIO初始化 */
    gpio_init_struct.Pin = KEY0_GPIO_PIN;                       /* KEY0引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY0_GPIO_PORT, &gpio_init_struct);           /* KEY0引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = KEY1_GPIO_PIN;                       /* KEY1引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY1_GPIO_PORT, &gpio_init_struct);           /* KEY1引脚模式设置,上拉输入 */

    gpio_init_struct.Pin = KEY2_GPIO_PIN;                       /* KEY2引脚 */
    gpio_init_struct.Mode = GPIO_MODE_INPUT;                    /* 输入 */
    gpio_init_struct.Pull = GPIO_PULLUP;                        /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;              /* 高速 */
    HAL_GPIO_Init(KEY2_GPIO_PORT, &gpio_init_struct);           /* KEY2引脚模式设置,上拉输入 */
}

/**
 * @brief  读取KEY0按键状态
 * @return 按键状态，COT_KEY_ON表示按下，COT_KEY_OFF表示松开
 */
static cotKeyState_e ReadKey0(void)
{
    /* 严格判断只有KEY0按下的情况 */
    return (GPIO_GetKEY() == KEY_CODE_0) ? COT_KEY_ON : COT_KEY_OFF;
}

/**
 * @brief  读取KEY1按键状态
 * @return 按键状态，COT_KEY_ON表示按下，COT_KEY_OFF表示松开
 */
static cotKeyState_e ReadKey1(void)
{
    /* 严格判断只有KEY1按下的情况 */
    return (GPIO_GetKEY() == KEY_CODE_1) ? COT_KEY_ON : COT_KEY_OFF;
}

/**
 * @brief  读取KEY2按键状态
 * @return 按键状态，COT_KEY_ON表示按下，COT_KEY_OFF表示松开
 */
static cotKeyState_e ReadKey2(void)
{
    /* 严格判断只有KEY2按下的情况 */
    return (GPIO_GetKEY() == KEY_CODE_2) ? COT_KEY_ON : COT_KEY_OFF;
}

/**
 * @brief  KEY0按键回调处理函数
 */
static void OnKey0Press(cotKey_t key)
{
    if (!cotKey_IsLongPress(key))  /* 判断是否触发了长按 */
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            printf("KEY0 pressed\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            printf("KEY0 released\r\n");
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            printf("KEY0 long press detected\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            printf("KEY0 long press released\r\n");  
        }
    }
}

/**
 * @brief  KEY1按键回调处理函数
 */
static void OnKey1Press(cotKey_t key)
{
    if (!cotKey_IsLongPress(key))  /* 判断是否触发了长按 */
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            printf("KEY1 pressed\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            printf("KEY1 released\r\n");
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            printf("KEY1 long press detected\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            printf("KEY1 long press released\r\n");
        }
    }
}

/**
 * @brief  KEY2按键回调处理函数
 */
static void OnKey2Press(cotKey_t key)
{
    if (!cotKey_IsLongPress(key))  /* 判断是否触发了长按 */
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 按下首次触发 */
        {
            printf("KEY2 pressed\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 识别到短按 */
        {
            printf("KEY2 released\r\n");
        }
    }
    else
    {
        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_PRESS)) /* 识别到长按 */
        {
            printf("KEY2 long press detected\r\n");
        }

        if (cotKey_IsTriggerWayMet(key, COT_KEY_TRIGGER_WAY_LOSSEN)) /* 长按松开 */
        {
            printf("KEY2 long press released\r\n");
        }
    }
}

/**
 * @brief  按键初始化
 */
void FML_KEY_Init(void)
{
    static cotKeyCfg_t s_keyTable[KEY_MAX_NUM] =
    {
        {.pfnKeyState = ReadKey0},
        {.pfnKeyState = ReadKey1},
        {.pfnKeyState = ReadKey2},
    };

    /* 初始化按键IO */
    InitKeyIo();
    
    /* 初始化COT按键模块 */
    cotKey_Init(s_keyTable, KEY_MAX_NUM);
    
    /* 注册按键回调 */
    cotKey_Listen(KEY0, OnKey0Press);
    cotKey_Listen(KEY1, OnKey1Press);
    cotKey_Listen(KEY2, OnKey2Press);

    /* 统一配置所有按键为长按模式 */
    cotKey_ConfigLongPressMode(KEY0, 1500, 500);      /* 1.5秒长按，0.5秒重复 */
    cotKey_ConfigLongPressMode(KEY1, 1500, 500);      /* 1.5秒长按，0.5秒重复 */
    cotKey_ConfigLongPressMode(KEY2, 1500, 500);      /* 1.5秒长按，0.5秒重复 */
}
